package top.hmtools.prikey;

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Random;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SnowflakeTools {
	
	private final static Logger logger = LoggerFactory.getLogger(SnowflakeTools.class);

	private static Sequence SEQUENCE= null;
	
	/**
	 * 生成long数据类型的Snowflake id
	 * <br>机器id基于网卡mac地址生成。
	 * <br>数据中心id基于网卡ip地址生成。
	 * @return
	 */
	public static  long generateLongId(){
		return generateLongId(0, 0);
	}
	
	/**
	 * 生成long数据类型的Snowflake id
	 * <br>机器id基于网卡mac地址生成。
	 * <br>数据中心id基于网卡ip地址生成。
	 * @param workerId 数据小于1时，基于网卡mac地址生成。
	 * @param dataCenterId 数据小于1时，基于网卡ip地址生成。
	 * @return
	 */
	public static  long generateLongId(long workerId,long dataCenterId){
		if(workerId<1){
			workerId = getWorkerId();
		}
		if(dataCenterId<1){
			dataCenterId = getDataCenterId();
		}
		if(SEQUENCE == null){
			synchronized (Sequence.class) {
				if(SEQUENCE == null){
					SEQUENCE = new Sequence(workerId, dataCenterId);
				}
			}
		}
		
		return SEQUENCE.nextId();
	}
	
	/**
	 * 生成String数据类型的Snowflake id
	 * <br>机器id基于网卡mac地址生成。
	 * <br>数据中心id基于网卡ip地址生成。
	 * @return
	 */
	public static String generateStringId(){
		return generateStringId(0, 0);
	}

	/**
	 * 生成String数据类型的Snowflake id
	 * <br>机器id基于网卡mac地址生成。
	 * <br>数据中心id基于网卡ip地址生成。
	 * @param workerId 数据小于1时，基于网卡mac地址生成。
	 * @param dataCenterId 数据小于1时，基于网卡ip地址生成。
	 * @return
	 */
	public static String generateStringId(long workerId,long dataCenterId){
		return String.valueOf(generateLongId(workerId, dataCenterId));
	}
	
	/**
	 * 通过对mac地址取模，获取机器id
	 * @throws SocketException
	 * @throws UnknownHostException
	 */
	private static long getWorkerId(){
		Random random = new Random();
		long result = random.nextInt(31);
		try {
			// 得到IP，输出PC-201309011313/122.206.73.83
			InetAddress ia = InetAddress.getLocalHost();
			
			// 获取网卡，获取地址
			byte[] mac = NetworkInterface.getByInetAddress(ia).getHardwareAddress();
			StringBuffer sb = new StringBuffer("");
			for (int i = 0; i < mac.length; i++) {
				// 字节转换为整数
				int temp = mac[i] & 0xff;
				sb.append(String.valueOf(temp));
			}
			result= Long.parseLong(sb.toString())%31;
		} catch (Exception e) {
			//skip
		}
		if(logger.isDebugEnabled()){
			logger.debug("当前生成snowflake id用的机器id（基于网卡mac地址生成）是：{}",result);
		}
		return result;
	}
	
	/**
	 * 根据ip地址生成数据中心id
	 * @return
	 */
	private static long getDataCenterId(){
		Random random = new Random();
		long result = random.nextInt(31);
		try {
			String ipStr = InetAddress.getLocalHost().getHostAddress().toString();
			ipStr = ipStr.replaceAll("\\.", "");
			result = Long.parseLong(ipStr)%31;
		} catch (Exception e) {
			// skip
		}
		if(logger.isDebugEnabled()){
			logger.debug("当前生成snowflake id用的数据中心id（基于网卡IP地址生成）是：{}",result);
		}
		return result;
	}
	
	public static void main(String[] args){
		
	}
}
